//
//  ViewController.m
//  CCSD
//
//  Created by peterwang on 5/29/15.
//  Copyright (c) 2015 NeuroSky. All rights reserved.
//

#import "ViewController.h"
#import "profileController.h"

static NSString * const VERSION      = @"App Version: 2.0.1";

@interface ViewController (){
    TGStream *tgStream;
    TGLibECG * tglibECG;
    profileController *profileController_I;
    
//user info
    NSString *name;
    NSString *age;
    NSString *gender;
    NSString *weight;
    NSString *height;

//heart info
    NSString *RRInterval_S;
    NSString *HeartRate_S;
    NSString *RobustHR_S;
    NSString *HRV_S;
    NSString *Mood_S;
    NSString *HeartAge_S;
    NSString *Stress_S;
    NSString *SignalQuality_S;
    NSString *RPeakDetected_S;
    NSString *HeartBeatCount_S;
    NSString *overallSignalQuality_S;
    
    
    dispatch_queue_t writeDataQueue;
    dispatch_queue_t ecgQueue;

    NSFileHandle *rawDatahandler;
    NSFileHandle *heartDatahandler;
  
    int       poorSignalValue;
    BOOL isZoom1X;
    BOOL isGridOn;
    BOOL logEnable;
    BOOL isSimpleMode;
    
    //recordFlag
    BOOL recordEnable;

    NSTimer *getSignalQualityTimer;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self  setupButtons];
    
    [self setuplabels];

    profileController_I=[self.storyboard instantiateViewControllerWithIdentifier:@"profile" ];
    
    tgStream =[TGStream sharedInstance];
    tgStream.delegate=self;
    
    tglibECG = [[TGLibECG alloc] init];
    [tglibECG setDelegate:self];

    NSString *sdkVersion=[NSString stringWithFormat:@"SDK Version: %@/%@ ",[tgStream getVersion],[tglibECG getVersion]];
    _sdkVersion.text= sdkVersion;
    
    _appVersion.text=VERSION;
    
    writeDataQueue=dispatch_queue_create("writeData_queue", DISPATCH_QUEUE_SERIAL);
    ecgQueue=dispatch_queue_create("ecg_queue", DISPATCH_QUEUE_SERIAL);

    //flag init
    isGridOn=NO;
    isZoom1X=YES;
    logEnable=NO;
    isSimpleMode=NO;
    recordEnable=NO;
    
    //line graph view init
    _ECGGraph->cursorEnabled=NO;
    _ECGGraph->gridEnabled=NO;
    
    NSLog(@"profile %p",_profile);
    NSLog(@"start %p",_start);
    NSLog(@"stop %p",_stop);
    NSLog(@"zoom %p",_zoom);
    NSLog(@"gridOn %p",_gridOn);
    NSLog(@"modeSwitch %p",_modeSwitch);

}

-(void) setString2UserDefaultOnce{
    NSUserDefaults *userSetting=[NSUserDefaults standardUserDefaults];

    [userSetting setObject:@"TOM" forKey:nameKey ];
    [userSetting setObject:@"Male" forKey:genderKey ];
    [userSetting setObject:@"23" forKey:ageKey ];
    [userSetting setObject:@"175" forKey:heightKey ];
    [userSetting setObject:@"60" forKey:weightKey ];
    [userSetting synchronize];
 //   NSLog(@"user setting once");
}

-(void) viewWillAppear:(BOOL)animated{
    
    NSUserDefaults *userSetting=[NSUserDefaults standardUserDefaults];
    if (![userSetting objectForKey:nameKey]) {
        
        [self setString2UserDefaultOnce];
        name=[userSetting objectForKey:nameKey];
        age=[userSetting objectForKey:ageKey];
        gender=[userSetting objectForKey:genderKey];
        weight=[userSetting objectForKey:weightKey];
        height=[userSetting objectForKey:heightKey];
        
    }
    else{
        name=[userSetting objectForKey:nameKey];
        age=[userSetting objectForKey:ageKey];
        gender=[userSetting objectForKey:genderKey];
        weight=[userSetting objectForKey:weightKey];
        height=[userSetting objectForKey:heightKey];
    }
    NSLog(@"name %@\n age %@\n gender %@\n weight %@\n height %@\n",name,age,gender,weight,height);

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

}

#pragma mark - setup view
-(void)setupButtons{
    NSArray *buttonsArray=[NSArray arrayWithObjects:_profile,_start,_stop,_zoom,_gridOn,_modeSwitch,nil];
    
    for (UIButton *button in buttonsArray)
    {
        button.layer.borderColor=[UIColor blueColor].CGColor;
        button.layer.borderWidth=2;
        button.titleLabel.font=[UIFont fontWithName:@"Optima" size:14];
        [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    }
}

-(void)setuplabels{
    NSArray *labelArray=[NSArray arrayWithObjects:_rrInterval,
                         _heartRate,
                         _robustHR,
                         _hrv,
                         _mood,
                         _heartAge,
                         _stress,
                         _signalQuality,
                         _appVersion,
                         _sdkVersion,
                         _RPeakDetected,
                         _HeartBeatCount,
                         _overallSignalQuality,
                        nil];
    for (UILabel *label in labelArray) {
        label.font=[UIFont fontWithName:@"Optima" size:14];
    }
    
}

#pragma mark - ECG delegate
-(void)exceptionECGMessage:(ECGException)excepType{
    NSLog(@"exception happend %d",(int)excepType);
}

static int HeartBeatCountNumber=0;
static int RPeakDetectedCountNumber=0;

- (void)dataReceived:(NSDictionary *)data {
    
    //raw data
    if ([data valueForKey:dicECGsmoothedWave]) {
        
        NSString *smoothWaveString=[NSString stringWithFormat:@"%@",[data valueForKey:dicECGsmoothedWave ]];
        
        [_ECGGraph addValue:[smoothWaveString intValue]];

        
    }
    
    //heart rate
    if([data valueForKey:dicECGheartRate])
    {
        
        NSString *HeartRate=[NSString stringWithFormat:@"HeartRate:%@",[data valueForKey:dicECGheartRate]];
        HeartRate_S=HeartRate;
//        NSLog(@"dicECGheartRate");
        dispatch_async(dispatch_get_main_queue(), ^{
            
            _heartRate.text=HeartRate;
            
        });
        
    }
    
    //rpeakDetected
    if([data valueForKey:dicECGrpeakDetected])
    {
        NSString *RPeakDetected=[NSString stringWithFormat:@"RpeakDetected:%@",[data valueForKey:dicECGrpeakDetected] ];
   //     NSLog(@"dicECGrpeakDetected");
        RPeakDetected_S=RPeakDetected;
        
       NSLog(@"RPeakDetected %@",RPeakDetected);
        if ([[data valueForKey:dicECGrpeakDetected] intValue] ==1) {
            RPeakDetectedCountNumber++;

        }
        
        dispatch_async(dispatch_get_main_queue(), ^{
                _RPeakDetected.text = RPeakDetected;
        });
        
    }
    
    //robust HeartRate
    if([data valueForKey:dicECGheartRate])
    {
        
        NSString *RobustHR=[NSString stringWithFormat:@"RobustHeartRate:%@",[data valueForKey:dicECGrobustHeartRate]];
        RobustHR_S=RobustHR;
   //     NSLog(@"dicECGrobustHeartRate");
        dispatch_async(dispatch_get_main_queue(), ^{
            
            _robustHR.text=RobustHR;
            
        });
        
    }
 
    //rrInterval
    if([data valueForKey:dicECGr2rInterval]) {
        
 //       NSLog(@"dicECGr2rInterval");
        
        NSString *RRInterval=[NSString stringWithFormat:@"R_RInterval:%@", [data valueForKey:dicECGr2rInterval]];
        
        NSString *HeartBeatCount=[NSString stringWithFormat:@"HeartBeatCount:%d", [tglibECG getTotalRRintNum]];
        RRInterval_S=RRInterval;
        HeartBeatCount_S=HeartBeatCount;
        
        HeartBeatCountNumber++;
        
        dispatch_async(dispatch_get_main_queue(), ^{

            _rrInterval.text=RRInterval;
            _HeartBeatCount.text=HeartBeatCount;
        });
        
    }
    
    //hrv
    if([data valueForKey:dicECGhrv]) {
  //      NSLog(@"dicECGhrv");
        
        
        NSString *HRV=[NSString stringWithFormat:@"HRV:%@",[data valueForKey:dicECGhrv]];
        HRV_S=HRV;
        dispatch_async(dispatch_get_main_queue(), ^{
            _hrv.text=HRV;
            
        });
        
    }
    
    //heart age
    if ([data valueForKey:dicECGheartAge]) {
 //       NSLog(@"dicECGheartAge");
        
        NSString *HeartAge=[NSString stringWithFormat:@"HeartAge:%@",[data valueForKey:dicECGheartAge]];
        HeartAge_S=HeartAge;
        dispatch_async(dispatch_get_main_queue(), ^{
            _heartAge.text=HeartAge;
            
        });
        
    }
    
    //mood
    if ([data valueForKey:dicECGmood]) {
  //      NSLog(@"dicECGmood");
        
        NSString *Mood=[NSString stringWithFormat:@"Mood:%@",[data valueForKey:dicECGmood]];
        Mood_S=Mood;
        dispatch_async(dispatch_get_main_queue(), ^{
            _mood.text=Mood;
            
        });
        
        
    }
    
    //stress
    if ([data valueForKey:dicECGstress]) {
   //     NSLog(@"dicECGstress");
        
        NSString *Stress=[NSString stringWithFormat:@"Stress:%@",[data valueForKey:dicECGstress]];
        Stress_S=Stress;
        dispatch_async(dispatch_get_main_queue(), ^{
            _stress.text=Stress;
            
        });
        
    }
}

-(void) onDataReceived:(NSInteger)datatype data:(int)data obj:(NSObject *)obj deviceType:(DEVICE_TYPE)deviceType
{

    
    if (datatype== BodyDataType_CODE_POOR_SIGNAL) {
        
        poorSignalValue=data;

    }
    
    if (datatype == BodyDataType_CODE_RAW) {
        
        if (poorSignalValue ==200) {
            
            
            dispatch_async(writeDataQueue, ^{
                
                NSString *rawData=[NSString stringWithFormat:@"%d\n",data];
                NSData   *rawNsData=[rawData dataUsingEncoding:NSUTF8StringEncoding];
                
                [rawDatahandler seekToEndOfFile];
                [rawDatahandler writeData:rawNsData];
                
                
            });
            
            dispatch_async(ecgQueue, ^{
                [tglibECG requestECGAnalysis: (int)data  withPoorSignal:200];
            });
        }
    }
    
    
}

#pragma mark - IBAction
- (IBAction)profileAction:(id)sender {
    
    [self presentViewController:profileController_I animated:YES completion:nil];
}

-(void)setupECG{
    
    int ageInt=[age intValue];
    int heightInt=[height intValue];
    int weightInt=[weight intValue];
    
    [tglibECG resetECGAnalysis];
//    [tglibECG resetHeartAge];
//    [tglibECG resetStress];
  
    [tglibECG setHRVOutputInterval:30];
    [tglibECG setMoodOutputPoint:30];
    
    [tglibECG enableNSLogMessages:false];
    
    [tglibECG setHeartAgeOutputPoint:40];
    [tglibECG setHeartAgeRecordNumber:2];
    
    [tglibECG setHeartAgeParameters:name withAge:ageInt  withPath:@""];
    
    if ([gender isEqualToString:@"Male"]) {
        [tglibECG setStressParameters:name withGender:true withAge:ageInt withHeight:heightInt withWeight:weightInt withPath:@""];
        
    }
    else{
        [tglibECG setStressParameters:name withGender:false withAge:ageInt withHeight:heightInt withWeight:weightInt withPath:@""];
        
    }
    
    [tglibECG setStressOutputInterval:30];
    
    NSLog(@"name%@ age%d gender%@ height%d weight%d ", name,ageInt,gender,heightInt,weightInt);
    
//    NSLog(@"ECG SDK Version: %@, Algo Version: %@",[tglibECG getVersion],[tglibECG getAlgoVersion]);
    
}

-(void)initLabel{
    
    _rrInterval.text=@"R_RInterval:";
    _heartRate.text=@"HeartRate:";
    _robustHR.text=@"RobustHeartRate:";
    _hrv.text           =@"HRV:";
    _mood.text       =@"Mood:";
    _heartAge.text  =@"HeartAge:";
    _stress.text        =@"Stress:";
    _signalQuality.text=@"SignalQuality:";

    _RPeakDetected.text=@"RpeakDetected:";
    _HeartBeatCount.text=@"HeartBeatCount:";
    _overallSignalQuality.text=@"OverallSignalQuality:";
    
}

-(void)createFile{
    
    NSFileManager *fileMangermant=[NSFileManager defaultManager];
    
    NSString  *documentDir=[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    
    //record user raw data
    NSString *rawfileName=[NSString stringWithFormat:@"%@-%@",name,[self convertDate2String:[NSDate date]]];
    NSString *rawfilePath=[documentDir stringByAppendingPathComponent:rawfileName] ;
    NSLog(@"rawfilePath %@",rawfilePath);
    
    [fileMangermant createFileAtPath:rawfilePath contents:nil attributes:nil];
    rawDatahandler=[NSFileHandle fileHandleForWritingAtPath:rawfilePath];
    
    
    //record user heart info
    NSString *heartfileName=[NSString stringWithFormat:@"%@-heart-%@",name,[self convertDate2String:[NSDate date]]];
    NSString *heartfilePath=[documentDir stringByAppendingPathComponent:heartfileName] ;
    NSLog(@"heartfilePath %@",heartfilePath);

    [fileMangermant createFileAtPath:heartfilePath contents:nil attributes:nil];
    heartDatahandler=[NSFileHandle fileHandleForWritingAtPath:heartfilePath];
}

-(NSString *)convertDate2String:(NSDate *)date
{
    
    NSDateFormatter * formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"yyyy-MM-dd HH-mm-ss"];
    NSString *String= [formatter stringFromDate:date];
//    NSLog(@"convert time zone is %@",formatter.timeZone);
    
    NSArray *array=[String componentsSeparatedByString:@" "];
    NSString *dateString=[NSString stringWithFormat:@"%@-%@",[array objectAtIndex:0],[array objectAtIndex:1]];
    return dateString;
    
}

-(void) getSignalQuality{
    NSString *SignalQuality= [NSString stringWithFormat:@"SignalQuality: %d",[tglibECG getSignalQuality]];
    SignalQuality_S=SignalQuality;
    dispatch_async(dispatch_get_main_queue(), ^{
        _signalQuality.text = SignalQuality;
    });
}

- (IBAction)startAction:(id)sender {
    
    if (recordEnable==YES) {
        return;
    }
    
    [_ECGGraph cleardata];
  
    [self initLabel];
    [self setupECG];
    [self createFile];
    
    [tgStream initConnectWithAccessorySession];

    getSignalQualityTimer = [NSTimer scheduledTimerWithTimeInterval:4 target:self selector:@selector(getSignalQuality) userInfo:nil repeats:YES];

    recordEnable=YES;
    
    HeartBeatCountNumber=0;
    RPeakDetectedCountNumber=0;
}

-(void)getOverAllSignalQuality{

    NSString *overallSignalQuality = [NSString stringWithFormat:@"OverallSignalQuality: %f",[tglibECG getOverallSignalQuality]];
    overallSignalQuality_S=overallSignalQuality;
    dispatch_async(dispatch_get_main_queue(), ^{
        _overallSignalQuality.text = overallSignalQuality;
    });
}

-(void) writeFile{
    
    dispatch_async(writeDataQueue, ^{
        
        NSString *userData=[NSString stringWithFormat:@"name:%@\nage:%@\ngender:%@\nheight:%@\nweight:%@\n",name,age,gender,height,weight];
        NSData   *userNsData=[userData dataUsingEncoding:NSUTF8StringEncoding];
    
        NSString *heartData=[NSString stringWithFormat:@"%@\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n",RRInterval_S,HeartRate_S,RobustHR_S,HRV_S,Mood_S,HeartAge_S,Stress_S,SignalQuality_S,RPeakDetected_S,HeartBeatCount_S,overallSignalQuality_S];
        NSData   *heartNsData=[heartData dataUsingEncoding:NSUTF8StringEncoding];
        
        [heartDatahandler seekToEndOfFile];
        [heartDatahandler writeData:userNsData];
        [heartDatahandler writeData:heartNsData];
        [heartDatahandler closeFile];
        
    });
    
}

- (IBAction)stopAction:(id)sender {
    
    if (recordEnable==NO) {
        return;
    }
    
    if ([getSignalQualityTimer isValid]) {
        [getSignalQualityTimer invalidate];

    }

    
    [tgStream tearDownAccessorySession];

    [rawDatahandler closeFile];
    
    [self getOverAllSignalQuality];
    
    [self writeFile];
    
    recordEnable=NO;
    
    NSLog(@"RpeakDetected %d HeartBeatCount %d",RPeakDetectedCountNumber,HeartBeatCountNumber);
}

- (IBAction)zoomAction:(id)sender {
    
    isZoom1X=!isZoom1X;
    
    if (isZoom1X) {
        [_zoom setTitle:@"1x" forState:UIControlStateNormal];
        _ECGGraph->yAxisMax=3072;
        _ECGGraph->yAxisMin=-3072;
        _ECGGraph->xAxisMax=6;
        [_ECGGraph setNeedsDisplay];

    }else{
        [_zoom setTitle:@"2x" forState:UIControlStateNormal];

        _ECGGraph->yAxisMax=1536;
        _ECGGraph->yAxisMin=-1536;
        _ECGGraph->xAxisMax=3;
        [_ECGGraph setNeedsDisplay];

    }
}

- (IBAction)gridOnAction:(id)sender {

    isGridOn=!isGridOn;
    
    if (isGridOn) {
        _ECGGraph->gridEnabled=YES;
        [_ECGGraph setNeedsDisplay];
        [_gridOn setTitle:@"Grid On" forState:UIControlStateNormal];
    }else{
        _ECGGraph->gridEnabled=NO;
        [_ECGGraph setNeedsDisplay];
        [_gridOn setTitle:@"Grid Off" forState:UIControlStateNormal];
    }
    
}

- (IBAction)modeSwitchAction:(id)sender {
    isSimpleMode=!isSimpleMode;
    if (isSimpleMode) {
        _RPeakDetected.hidden=YES;
        _HeartBeatCount.hidden=YES;
        _overallSignalQuality.hidden=YES;
        
        [_modeSwitch setTitle:@"Simple Mode" forState:UIControlStateNormal];

    }else{
        _RPeakDetected.hidden=NO;
        _HeartBeatCount.hidden=NO;
        _overallSignalQuality.hidden=NO;
        
        [_modeSwitch setTitle:@"Full Mode" forState:UIControlStateNormal];

        
    }
    
}


@end
